package com.codefish.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.codefish.common.PermissionConstants;
import com.codefish.dto.MenuTreeDto;
import com.codefish.entity.*;
import com.codefish.mapper.SysPermissionDao;
import com.codefish.service.SysPermissionApiService;
import com.codefish.service.SysPermissionMenuService;
import com.codefish.service.SysPermissionPointService;
import com.codefish.service.SysPermissionService;
import com.codefish.util.BeanMapUtils;
import com.codefish.util.IdWorker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * 权限
 *
 * @author codefish
 * @email cool_fish@aliyun.com
 * @date 2021-04-15 17:58:46
 */
@Service("sysPermissionService")
public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionDao, SysPermissionEntity> implements SysPermissionService {

    @Autowired
    private SysPermissionDao permissionDao;

    @Autowired
    private SysPermissionMenuService menuService;

    @Autowired
    private SysPermissionPointService pointService;

    @Autowired
    private SysPermissionApiService apiService;


    /**
     * 新增 Permission
     *
     * @param userId permission
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public int savePermission(Long userId, SysPermissionEntity permission) {
        int saveFlag = 0;


        IdWorker idWorker = new IdWorker();
        String nextId = idWorker.nextId() + "";

        permission.setId(nextId);
        permission.setCreateId(userId);

        String type = permission.getType();


        //toMap
        Map<String, Object> beanMap = BeanMapUtils.beanToMap(permission);

        // 权限类型 1为菜单 2为功能 3为API
        switch (type) {
            case PermissionConstants.PERMISSION_MENU:
                SysPermissionMenuEntity menuEntity = BeanMapUtils.mapToBean(beanMap, SysPermissionMenuEntity.class);
                saveFlag = menuService.saveOne(menuEntity);
                break;
            case PermissionConstants.PERMISSION_POINT:
                SysPermissionPointEntity pointEntity = BeanMapUtils.mapToBean(beanMap, SysPermissionPointEntity.class);
                saveFlag = pointService.saveOne(pointEntity);
                break;
            case PermissionConstants.PERMISSION_API:
                SysPermissionApiEntity apiEntity = BeanMapUtils.mapToBean(beanMap, SysPermissionApiEntity.class);
                saveFlag = apiService.saveOne(apiEntity);
                break;
        }
        if (null == permission.getPid() || "".equals(permission.getPid())){
            permission.setPid("0");
            permission.setType(PermissionConstants.PERMISSION_MENU);
        }
        saveFlag = permissionDao.insert(permission);

        return saveFlag;
    }

    /**
     * 查询权限数量
     *
     * @param permission
     * @return
     */
    @Override
    public int selectCount(SysPermissionEntity permission) {
        String pid = permission.getPid();
        String name = permission.getName();
        QueryWrapper<SysPermissionEntity> queryWrapper = new QueryWrapper<SysPermissionEntity>()
                .eq("name", name)
                .eq("pid", pid)
                .eq("is_del", 0);
        if (!ObjectUtils.isEmpty(permission.getId())) {
            queryWrapper.ne("id", permission.getId());
        }
        Integer count = permissionDao.selectCount(queryWrapper);

        return count;
    }

    /**
     * 修改权限
     *
     * @param userId
     * @param permission
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public int updatePermission(Long userId, SysPermissionEntity permission) {
        int updateFlag = 0;

        Map<String, Object> beanMap = BeanMapUtils.beanToMap(permission);
        String id = permission.getId();
        String type = permission.getType();

        switch (type) {
            case PermissionConstants.PERMISSION_MENU:
                SysPermissionMenuEntity menuEntity = BeanMapUtils.mapToBean(beanMap, SysPermissionMenuEntity.class);
                menuEntity.setId(id);
                menuEntity.setUpdateTime(new Date());
                boolean updateMenu = menuService.updateById(menuEntity);
                if (updateMenu) {
                    updateFlag = 1;
                }
                break;
            case PermissionConstants.PERMISSION_POINT:
                SysPermissionPointEntity pointEntity = BeanMapUtils.mapToBean(beanMap, SysPermissionPointEntity.class);
                pointEntity.setId(id);
                pointEntity.setUpdateTime(new Date());
                boolean updatePoint = pointService.updateById(pointEntity);
                if (updatePoint) {
                    updateFlag = 1;
                }
                break;
            case PermissionConstants.PERMISSION_API:
                SysPermissionApiEntity apiEntity = BeanMapUtils.mapToBean(beanMap, SysPermissionApiEntity.class);
                apiEntity.setId(id);
                apiEntity.setUpdateTime(new Date());
                boolean updateApi = apiService.updateById(apiEntity);
                if (updateApi) {
                    updateFlag = 1;
                }
                break;
        }
        permission.setUpdateTime(new Date());
        int update = permissionDao.updateById(permission);
        if (update == 1) {
            updateFlag = 1;
        }

        return updateFlag;
    }

    /**
     * 获取菜单
     *
     * @param userId
     * @return
     */
    @Override
    public List<MenuTreeDto> getMenuTree(Long userId, Map<String, Object> params) {


        // todo 获取用户角色相对于api列表

        // 构建条件
        QueryWrapper<SysPermissionEntity> queryWrapper = new QueryWrapper<SysPermissionEntity>()
                .ne("is_del", 1)
                .eq("state", 1);

        if (null != params.get("id") && !params.get("id").toString().isEmpty()) {
            queryWrapper.eq("id", new Long(params.get("id").toString()));
        }
        if (null != params.get("name") && !params.get("name").toString().isEmpty()) {
            queryWrapper.like("name", params.get("name").toString());
        }
        if (null != params.get("path") && !params.get("path").toString().isEmpty()) {
            queryWrapper.eq("path", params.get("path").toString());
        }

        List<MenuTreeDto> menuTree = new ArrayList<>();
        List<SysPermissionEntity> sysPermissionEntities = permissionDao.selectList(queryWrapper);

        sysPermissionEntities.forEach(one -> {
            if (one.getType() != null && PermissionConstants.PERMISSION_MENU.equals(one.getType())) {
                MenuTreeDto menuDto = new MenuTreeDto();
                menuDto.setId(one.getId());
                menuDto.setName(one.getName());
                menuDto.setPath(one.getPath());
                menuTree.add(menuDto);
            }
        });

        // 删除 一级菜单消费过的菜单
        menuTree.forEach(menu -> {
            String id = menu.getId();
            for (int i = 0; i < sysPermissionEntities.size(); i++) {

                if (id == sysPermissionEntities.get(i).getId()) {
                    sysPermissionEntities.remove(i);
                }
            }
        });

        // 构建二级菜单
        if (menuTree.size() < 1) {
            return menuTree;
        }
        for (int i = 0; i < menuTree.size(); i++) {
            MenuTreeDto menu = menuTree.get(i);
            List<MenuTreeDto> childrenList = this.buildChildren(menu.getId(), sysPermissionEntities);
            menu.setChildren(childrenList);
            // 删除 二级菜单消费过的菜单
            for (int j = 0; j < sysPermissionEntities.size(); j++) {
                SysPermissionEntity sysPermissionEntity = sysPermissionEntities.get(j);
                if (sysPermissionEntity.getId().equals(menu.getId())) {
                    sysPermissionEntities.remove(j);
                }
            }
            // 构建三级菜单
            if (childrenList.size() < 1) {
                return menuTree;
            }
            childrenList.forEach(point -> {
                String pointId = point.getId();
                List<MenuTreeDto> apiList = this.buildChildren(pointId, sysPermissionEntities);
                point.setChildren(apiList);
            });
        }

        return menuTree;
    }

    /**
     * 删除单个
     * @param id
     * @return
     */
    @Override
    public boolean deleteOne(String id) {
        boolean deleteFlag = false;

        SysPermissionEntity entity = new SysPermissionEntity();
        entity.setId(id);
        entity.setIsDel(1);
        int i = baseMapper.updateById(entity);
        if (i == 1){
            return true;
        }


        return deleteFlag;
    }

    /**
     * 组建下级菜单
     *
     * @param menuId
     * @param originalMenuList
     * @return
     */
    private List<MenuTreeDto> buildChildren(String menuId, List<SysPermissionEntity> originalMenuList) {
        List<MenuTreeDto> menuChildrenTree = new ArrayList<>();

        for (int i = 0; i < originalMenuList.size(); i++) {
            SysPermissionEntity originalMenu = originalMenuList.get(i);
            String pid = originalMenu.getPid();
            if (pid != null && pid.equals(menuId)) {
                MenuTreeDto menuTreeDto = new MenuTreeDto();
                menuTreeDto.setId(originalMenu.getId());
                menuTreeDto.setName(originalMenu.getName());
                if (originalMenu.getPath() != null && !originalMenu.getPath().isEmpty()) {
                    menuTreeDto.setPath(originalMenu.getPath());
                }
                menuChildrenTree.add(menuTreeDto);
            }
        }

        return menuChildrenTree;
    }
    /**
     * 根据上级菜单获取下级菜单列表
     * @param baseCommonKey
     * @return
     */
    @Override
    public List<SysPermissionEntity> getListByMenuType(String baseCommonKey) {

        List<SysPermissionEntity> retList = new  ArrayList<>();

        switch (baseCommonKey) {
            case PermissionConstants.PERMISSION_POINT :
                retList = baseMapper.selectList(new QueryWrapper<SysPermissionEntity>()
                        .select("id","name")
                        .isNotNull("name")
                        .eq("is_del",0)
                        .eq("state",1)
                        .eq("type",PermissionConstants.PERMISSION_MENU));
                break;
            case PermissionConstants.PERMISSION_API :
                retList = baseMapper.selectList(new QueryWrapper<SysPermissionEntity>()
                        .select("id","name")
                        .isNotNull("name")
                        .eq("is_del",0)
                        .eq("state",1)
                        .eq("type",PermissionConstants.PERMISSION_POINT));
                break;
        }

        return retList;
    }
}